package com.design.oop.util;

import java.io.File;
import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
import java.net.HttpURLConnection;
import java.net.URL;

import android.net.Uri;
import android.os.Environment;

import com.design.oop.WheatBeerApplication;

public class FileUtil {
	public static String getExternalRootDir() {
		String root = "";
		if (isAvailableExternalMemory()) {
			root = Environment.getExternalStorageDirectory().getAbsolutePath() + "/Android/data/" + WheatBeerApplication.getContext().getPackageName();

			File file = new File(root);
			if (!file.exists()) {
				file.mkdir();
			}
		} else {
			root = WheatBeerApplication.getContext().getFilesDir().getAbsolutePath();
		}

		return root;
	}

	public static boolean isAvailableExternalMemory() {
		String state = Environment.getExternalStorageState();

		return Environment.MEDIA_MOUNTED.equals(state) && Environment.MEDIA_MOUNTED_READ_ONLY.equals(state) == false;
	}

	public static String getImageDir() {
		String tempDir = getExternalRootDir() + "/images";

		File file = new File(tempDir);

		if (!file.exists()) {
			file.mkdirs();
		}

		return tempDir;
	}

	public static String getThumbnailDir() {
		String tempDir = getExternalRootDir() + "/thumbnails";

		File file = new File(tempDir);

		if (!file.exists()) {
			file.mkdirs();
		}

		return tempDir;
	}

	public static File getImageCacheDir() {
		String tempDir = getExternalRootDir() + "/caches";

		File file = new File(tempDir);

		if (!file.exists()) {
			file.mkdirs();
		}

		return file;
	}

	public static String getExternalImageFilePath(String filename) {
		return FileUtil.getImageDir() + "/" + filename;
	}

	public static Uri getExternalImageFileUri(String filename) {
		return Uri.fromFile(new File(FileUtil.getExternalImageFilePath(filename)));
	}

	public static void downLoad(String url, String path) throws Exception {
		int read = 0;
		URL down = null;
		HttpURLConnection conn = null;
		InputStream is = null;
		FileOutputStream fos = null;
		File f = null;
		try {
			down = new URL(url);
			conn = (HttpURLConnection)down.openConnection();
			f = new File(path);
			if (f.exists()) {
				f.delete();
			}
			byte[] buffer = new byte[1024];
			is = conn.getInputStream();
			fos = new FileOutputStream(f);
			while ((read = is.read(buffer)) != -1) {
				fos.write(buffer, 0, read);
			}
		} finally {
			if (is != null) {
				is.close();
			}
			if (fos != null) {
				fos.close();
			}
			if (conn != null) {
				conn.disconnect();
			}
		}
	}

	public static void copyFile(String fromPath, String toPath) throws Exception {
		copyFile(new File(fromPath), new File(toPath));
	}

	public static void copyFile(File fromFile, File toFile) throws Exception {
		InputStream inStream = null;
		OutputStream outStream = null;

		FileUtil.delete(toFile);

		try {
			inStream = new FileInputStream(fromFile);
			outStream = new FileOutputStream(toFile);

			byte[] buffer = new byte[1024];

			int length;
			// copy the file content in bytes
			while ((length = inStream.read(buffer)) > 0) {
				outStream.write(buffer, 0, length);
			}

		} finally {
			if (inStream != null) {
				inStream.close();
			}
			if (outStream != null) {
				outStream.close();
			}
		}
	}

	public static void moveFile(String fromFilePath, String toFilePath) {
		File fromFile = new File(fromFilePath);
		File toFile = new File(toFilePath);

		moveFile(fromFile, toFile);
	}

	public static void moveFile(File fromFile, File toFile) {
		boolean result = fromFile.renameTo(toFile);

		if (result == false) {
			try {
				copyFile(fromFile, toFile);
				delete(fromFile);
			} catch (Exception e) {
				e.printStackTrace();
			}
		}
	}

	public static void delete(String filePath) {
		delete(new File(filePath));
	}

	public static void delete(File file) {
		if (file.exists()) {
			file.delete();
		}
	}

	/**
	 * Cleans a directory without deleting it.
	 *
	 * @param directory directory to clean
	 * @throws IOException in case cleaning is unsuccessful
	 */
	public static void cleanDirectory(File directory) {
		if (!directory.exists()) {
			String message = directory + " does not exist";
			throw new IllegalArgumentException(message);
		}

		if (!directory.isDirectory()) {
			String message = directory + " is not a directory";
			throw new IllegalArgumentException(message);
		}

		File[] files = directory.listFiles();
		if (files == null) { // null if security restricted
			throw new IllegalArgumentException("Failed to list contents of " + directory);
		}

		for (int i = 0; i < files.length; i++) {
			File file = files[i];
			delete(file);
		}
	}

	/**
	 * Gets the name minus the path from a full filename.
	 * <p>
	 * This method will handle a file in either Unix or Windows format.
	 * The text after the last forward or backslash is returned.
	 * <pre>
	 * a/b/c.txt --> c.txt
	 * a.txt     --> a.txt
	 * a/b/c     --> c
	 * a/b/c/    --> ""
	 * </pre>
	 * <p>
	 * The output will be the same irrespective of the machine that the code is running on.
	 *
	 * @param filename  the filename to query, null returns null
	 * @return the name of the file without the path, or an empty string if none exists
	 */
	public static String getName(String filename) {
		if (filename == null) {
			return null;
		}
		int index = filename.indexOf("/");
		return filename.substring(index + 1);
	}

	/**
	 * Gets the base name, minus the full path and extension, from a full filename.
	 * <p>
	 * This method will handle a file in either Unix or Windows format.
	 * The text after the last forward or backslash and before the last dot is returned.
	 * <pre>
	 * a/b/c.txt --> c
	 * a.txt     --> a
	 * a/b/c     --> c
	 * a/b/c/    --> ""
	 * </pre>
	 * <p>
	 * The output will be the same irrespective of the machine that the code is running on.
	 *
	 * @param filename  the filename to query, null returns null
	 * @return the name of the file without the path, or an empty string if none exists
	 */
	public static String getBaseName(String filename) {
		return removeExtension(getName(filename));
	}

	/**
	 * Gets the extension of a filename.
	 * <p>
	 * This method returns the textual part of the filename after the last dot.
	 * There must be no directory separator after the dot.
	 * <pre>
	 * foo.txt      --> "txt"
	 * a/b/c.jpg    --> "jpg"
	 * a/b.txt/c    --> ""
	 * a/b/c        --> ""
	 * </pre>
	 * <p>
	 * The output will be the same irrespective of the machine that the code is running on.
	 *
	 * @param filename the filename to retrieve the extension of.
	 * @return the extension of the file or an empty string if none exists.
	 */
	public static String getExtension(String filename) {
		if (filename == null) {
			return null;
		}
		int index = filename.lastIndexOf(".");
		if (index == -1) {
			return "";
		} else {
			return filename.substring(index + 1);
		}
	}

	//-----------------------------------------------------------------------
	/**
	 * Removes the extension from a filename.
	 * <p>
	 * This method returns the textual part of the filename before the last dot.
	 * There must be no directory separator after the dot.
	 * <pre>
	 * foo.txt    --> foo
	 * a\b\c.jpg  --> a\b\c
	 * a\b\c      --> a\b\c
	 * a.b\c      --> a.b\c
	 * </pre>
	 * <p>
	 * The output will be the same irrespective of the machine that the code is running on.
	 *
	 * @param filename  the filename to query, null returns null
	 * @return the filename minus the extension
	 */
	public static String removeExtension(String filename) {
		if (filename == null) {
			return null;
		}
		int index = filename.lastIndexOf(".");
		if (index == -1) {
			return filename;
		} else {
			return filename.substring(0, index);
		}
	}
}
